﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using POSPlus.DatabaseOperations;
using System.Data;
using POSPlus.EZBarTender.DatabaseOperations;
using System.Windows.Forms;

namespace POSPlus.EZBarTender.SignsPrinting
{
	public class SignsEditorModel : INotifyPropertyChanged
	{
		public delegate void NotifyPrintManager();
		public event NotifyPrintManager NotifyEventAction;

		#region Members
		private String _upc;
		private String _desc1;
		private String _desc2;
		private String _desc3;
		private String _desc4;
		private String _desc5;
		private double _normalPrice;
		private double _priceUom;
		private String _selling;
		private String _productSize;
		private DateTime _weekEnding;
		private double _youSave;
		private String _signType;
		private String _signSize;
		private String _jobName;
		private Int32 _duplicateCount;
		private event PropertyChangedEventHandler _propertyChanged;
		private String _corpCommandString;
		private String _localCommandString;
		public string CorpConnectionString;
		public string LocalConnectionString;
		private List<Sign> _signs;
		private Stack<Sign> _nextSignStack;
		private Stack<Sign> _previousSignStack;
		private Sign _currentSign;
		private String _batchNo;
		private List<Sign> _signsToRemove;
        private String _uom;
        private DateTime _startDate;
		#endregion

		#region Properties
		public Sign CurrentSign
		{
			get { return _currentSign; }
			set
			{
				if (_currentSign != value)
				{
					_currentSign = value;
					UpdateProperties();
					if(null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("CurrentSign"));
				}
			}
		}
		public String Upc
		{
			get { return _upc; }
			set
			{
				if (_upc != value)
				{
					_upc = value;
					if(_currentSign != null)
						_currentSign.Upc = value;
					if(null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("Upc"));
				}
			}
		}
		public String Description1
		{
			get { return _desc1; }
			set
			{
				if (_desc1 != value)
				{
					if(_currentSign != null)
						_currentSign.Desc1 = value;
					_desc1 = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("Description1"));
				}
			}
		}
		public String Description2
		{
			get { return _desc2; }
			set
			{
				if (_desc2 != value)
				{
					if (_currentSign != null)
						_currentSign.Desc2 = value;
					_desc2 = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("Description2"));
				}
			}
		}
		public String Description3
		{
			get { return _desc3; }
			set
			{
				if (_desc3 != value)
				{
					if (_currentSign != null)
						_currentSign.Desc3 = value;
					_desc3 = value;
					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("Description3"));
				}
			}
		}
		public String Description4
		{
			get { return _desc4; }
			set
			{
				if (_desc4 != value)
				{
					if (_currentSign != null)
						_currentSign.Desc4 = value;
					_desc4 = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("Description4"));
				}
			}
		}
		public String Description5
		{
			get { return _desc5; }
			set
			{
				if (_desc5 != value)
				{
					if (_currentSign != null)
						_currentSign.Desc5 = value;
					_desc5 = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("Description5"));
				}
			}
		}
		public double NormalPrice
		{
			get { return _normalPrice; }
			set
			{
				if (_normalPrice != value)
				{
					if (_currentSign != null)
						_currentSign.NormalPrice = value;
					_normalPrice = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("NormalPrice"));
				}
			}
		}
		public double PriceUom
		{
			get { return _priceUom; }
			set
			{
				if (_priceUom != value)
				{
					if (_currentSign != null)
						_currentSign.PriceUom = value;
					_priceUom = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("PriceUom"));
				}
			}
		}
		public String Selling
		{
			get { return _selling; }
			set
			{
				if (_selling != value)
				{
					if (_currentSign != null)
						_currentSign.Selling = value;
					_selling = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("Selling"));
				}
			}
		}
		public String ProductSize
		{
			get { return _productSize; }
			set
			{
				if (_productSize != value)
				{
					if (_currentSign != null)
						_currentSign.Size = value;
					_productSize = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("Size"));
				}
			}
		}
		public DateTime WeekEnding
		{
			get { return _weekEnding; }
			set
			{
				if (_weekEnding != value)
				{
					if (_currentSign != null)
						_currentSign.WeekEnding = value;
					_weekEnding = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("WeekEnding"));
				}
			}
		}
        public DateTime StartDate
        {
            get { return _startDate; }
            set
            {
                if (_startDate != value)
                {
                    if (_currentSign != null)
                        _currentSign.StartDate = value;

                    _startDate = value;

                    if (null != _propertyChanged)
                        _propertyChanged(this, new PropertyChangedEventArgs("StartDate"));
                }
            }
        }
		public double YouSave
		{
			get { return _youSave; }
			set
			{
				if (_youSave != value)
				{
					if (_currentSign != null)
						_currentSign.YouSave = value;
					_youSave = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("YouSave"));
				}
			}
		}
		public String SignType
		{
			get { return _signType; }
			set
			{
				if (_signType != value)
				{
					_signType = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("SignType"));
				}
			}
		}
		public String SignSize
		{
			get { return _signSize; }
			set
			{
				if (_signSize != value)
				{
					_signSize = value;
					Console.WriteLine("Property changed: " + _signSize);
					if(null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("SignSize"));
				}
			}
		}
		public String JobName
		{
			get { return _jobName; }
			set
			{
				if (_jobName != value)
				{
					_jobName = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("JobName"));
				}
			}
		}
		public Int32 DuplicateCount
		{
			get { return _duplicateCount; }
			set
			{
				if (_duplicateCount != value)
				{
					_duplicateCount = value;

					if (null != _propertyChanged)
						_propertyChanged(this, new PropertyChangedEventArgs("DuplicateCount"));
				}
			}
		}
		public String BatchNo
		{
			get { return _batchNo; }
			set
			{
				_batchNo = value;

				if (null != _propertyChanged)
					_propertyChanged(this, new PropertyChangedEventArgs("BatchNo"));
			}
		}
		public String CorpCommandString
		{
			get { return _corpCommandString; }
			set
			{
				if (_corpCommandString != value)
				{
					_corpCommandString = value;
				}
			}
		}
		public String LocalCommandString
		{
			get { return _localCommandString; }
			set
			{
				if (_localCommandString != value)
				{
					_localCommandString = value;
				}
			}
		}
        public String Uom
        {
            get { return _uom; }
            set
            {
                if (_uom != value)
                {
                    if (_currentSign != null)
                        _currentSign.Uom = value;

                    _uom = value;

                    //if (null != _propertyChanged)
                    //    _propertyChanged(this, new PropertyChangedEventArgs("Uom"));
                }
            }
        }
		#endregion

		public SignsEditorModel(string corpConnectionString, string localConnectionString)
		{
			_signsToRemove = new List<Sign>();
			_nextSignStack = new Stack<Sign>();
			_previousSignStack = new Stack<Sign>();
			CorpConnectionString = corpConnectionString;
			LocalConnectionString = localConnectionString;
			//DatabaseUpdate();
		}

		public event PropertyChangedEventHandler PropertyChanged
		{
			add { _propertyChanged += value; }
			remove { _propertyChanged -= value; }
		}

		private void UpdateProperties()
		{
			Upc = CurrentSign.Upc;
			Description1 = CurrentSign.Desc1;
			Description2 = CurrentSign.Desc2;
			Description3 = CurrentSign.Desc3;
			Description4 = CurrentSign.Desc4;
			Description5 = CurrentSign.Desc5;
			NormalPrice = CurrentSign.NormalPrice;
			PriceUom = CurrentSign.PriceUom;
			Selling = CurrentSign.Selling;
			ProductSize = CurrentSign.Size;
			WeekEnding = CurrentSign.WeekEnding;
			YouSave = CurrentSign.YouSave;
            Uom = CurrentSign.Uom;
		}

		internal void NextSign()
		{
			DuplicateCount = 1;
			if (_nextSignStack.Count > 0)
			{
				_previousSignStack.Push(_nextSignStack.Pop());
				CurrentSign = _nextSignStack.Peek();
				UpdateProperties();
			}
			else
			{
				Clear();
			}
		}

		public void Clear()
		{
			Description1 = "";
			Description2 = "";
			Description3 = "";
			Description4 = "";
			Description5 = "";
			DuplicateCount = 1;
			NormalPrice = 0;
			PriceUom = 0;
			Selling = "";
			ProductSize = "";
			WeekEnding = new DateTime(1900, 1, 1);
			YouSave = 0;
			SignType = "";
			SignSize = "";
			Upc = "";
            Uom = "";
			CurrentSign = new Sign(LocalConnectionString);
		}

		internal void PreviousSign()
		{
			DuplicateCount = 1;
			if (_previousSignStack.Count > 0)
			{
				_nextSignStack.Push(_previousSignStack.Pop());
				CurrentSign = _nextSignStack.Peek();
				UpdateProperties();
			}
			else
			{
				Clear();
			}
		}

		public void DatabaseUpdate()
		{
			DuplicateCount = 1;
			_signs = Sign.GetAllNew(LocalConnectionString, true);
			if (_signs.Count < 1)
				_signs = Sign.GetAll(LocalConnectionString);

			foreach (Sign sign in _signs)
			{
				_previousSignStack.Push(sign);
			}

			while (_previousSignStack.Count > 0)
			{
				_nextSignStack.Push(_previousSignStack.Pop());
			}

			//CurrentSign = _nextSignStack.Peek();
			//UpdateProperties();
			_batchNo = "";
			_desc1 = "";
			_desc2 = "";
			_desc3 = "";
			_desc4 = "";
			_desc5 = "";
			_duplicateCount = 1;
			_jobName = "";
			_normalPrice = 0;
			_priceUom = 0;
			_productSize = "";
			_selling = "";
			_signSize = "";
			_signType = "";
			_upc = "";
            _uom = "";
			_weekEnding = DateTime.Now;
			_youSave = 0;
		}

		private void SplitDescription(String description)
		{
			if (description.Length <= 18)
				Description1 = description;
			else
			{
				String[] splitDescription = description.Split(' ');
				if (splitDescription.Length > 1)
				{
					String line1 = "";
					String line2 = "";
					int current = 0;
					do
					{
						line1 += splitDescription[current] + " ";
						current++;
					} while (line1.Length < 18 && current < splitDescription.Length);

					while (line2.Length < 24 && current < splitDescription.Length)
					{
						line2 += splitDescription[current] + " ";
						current++;
					}

					Description1 = line1.Trim();
					Description2 = line2.Trim();
				}
				else
				{
					if (description.Length <= 42)
					{
						Description1 = description.Substring(0, 18);
						Description2 = description.Substring(18, description.Length - 18);
					}
					else
					{
						Description1 = description.Substring(0, 18);
						Description2 = description.Substring(18, 24);
					}
				}
			}
		}

		public void CommitChanges()
		{
			SignPrintInfo signInfo = new SignPrintInfo(LocalConnectionString);
			signInfo.Upc = Upc;
			signInfo.Description1 = Description1;
			signInfo.Description2 = Description2;
			signInfo.Description3 = Description3;
			signInfo.Description4 = Description4;
			signInfo.Description5 = Description5;
			signInfo.NormalPrice = (decimal)NormalPrice;
			signInfo.Size = ProductSize;
			signInfo.SpecialPrice = Selling;
			signInfo.UnitSP = PriceUom;
			signInfo.WeekEnding = WeekEnding;
			signInfo.YouSave = (decimal)YouSave;
			signInfo.BatchNo = BatchNo;
            signInfo.Uom = Uom;
            signInfo.StartDate = StartDate;

			try
			{
				if (!signInfo.Update())
				{
					signInfo.Create();
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(
					"Unable to add item to Print Manager\n\n" + ex.Message,
					"Print Manager Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		public void RemoveSigns()
		{
			foreach (Sign sign in _signsToRemove)
				sign.Delete();
		}

		public void Editor_JobAdded()
		{
			Sign currentSign = CurrentSign;
			PrintManagerSign printManagerSign = new PrintManagerSign(LocalConnectionString);
			printManagerSign.Upc = Upc;
			printManagerSign.Copies = DuplicateCount;
			/*
			 * 1 UP - 14 x 11
			 * 1 UP - 13 x 10
			 * 1 UP - 8.5 x 11
			 * 1 UP - 7 x 11
			 * 2 UP - 7 x 5
			 * 4 UP - 5 x 3
			 */
			switch (SignSize)
			{
				case "1 UP - 14 x 11": printManagerSign.Type = "1UPX"; break;
				case "1 UP - 13 x 10": printManagerSign.Type = "1UPL"; break;
				case "1 UP - 8.5 x 11": printManagerSign.Type = "1UPM"; break;
				case "1 UP - 7 x 11": printManagerSign.Type = "1UPS"; break;
				case "2 UP - 7 x 5": printManagerSign.Type = "2UP"; break;
				case "4 UP - 5 x 3": printManagerSign.Type = "4UP"; break;
			}

			switch (SignType)
			{
				case "Super Sale": printManagerSign.Type += "SS"; break;
				case "Special Deal": printManagerSign.Type += "SD"; break;
				case "Now Even Lower": printManagerSign.Type += "NEL"; break;
				case "Smart Buy": printManagerSign.Type += "SB"; break;
				case "Bonus Bucks": printManagerSign.Type += "BB"; break;
			}
			printManagerSign.JobName = JobName;
			printManagerSign.BatchNo = BatchNo;
			try
			{
				printManagerSign.Create();
			}
			catch (Exception ex)
			{
				MessageBox.Show(
					"Unable to add item to Print Manager\n\n" + ex.Message,
					"Print Manager Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}

			if (NotifyEventAction != null)
				NotifyEventAction();
		}
	}
}